// 权限控制
// 登录权限 token 是否存在 路由守卫的前置守卫 如果有token

// 用户权限
// RBAC 权限控制 根据不同用户的权限 动态控制路由菜单的展示

import store from './store'
import router from './router'
// 进度条
import NProgress from 'nprogress'
import nprogress from 'nprogress'
import 'nprogress/nprogress.css'

// 动态路由
import { asyncRouters } from '@/router/asyncRouters'
// 开启进度条：NProgress.start()
// 结束进度条：NProgress.done()

// 定义白名单页面
const whileList = ['/404', '/login']

// 路由守卫
router.beforeEach(async(to, from, next) => {
  // 路由开始跳转前，开启进度条
  NProgress.start()
  const token = store.state.user.token
  if (token) {
    if (to.path === '/login') {
      next('/')
      // 因为路由守卫必须按照同一个路由成对出现
      // 如果在前置守卫中改变了跳转的地址，后置守卫会失效，但前置守卫是生效的
      // 所以导致了进度条开启后，无法结束的问题
      // 手动关闭进度条
      NProgress.done()
    } else {
      // 获取用户的基本资料应该在用户登录之后进行
      // 让用户进入每个页面丢能获取到用户的基本信息
      // 判断vuex 中 是否有用户信息数据 如果有则不需要再调用 如果没有才调用接口
      if (!store.state.user.userInfor.username) {
        // 用户权限控制
        // 位置：在获取用户个人信息之后，跳转页面的时候处理用户的权限
        const res = await store.dispatch('user/fetchUserInfor')
        const menus = res.roles.menus
        console.log(menus, '接口返回对的权限数据')
        console.log(asyncRouters, '需要过滤的原始动态路由')
        // 数据的过滤
        const filterRoutes = asyncRouters.filter(item => {
          return menus.includes(item.children[0].name)
        })
        console.log(filterRoutes, '过滤后的数组')
        // 3.将过滤出的动态路由放在路由实力上
        // 发现访问过滤之后的页面 出现 白屏 没有报错 也没有404
        // 说明路由实例上已经可以找到对应的路由表
        // 使用 addRoutes 方法，将用户可以访问的动态路由表，添加到路由表中
        router.addRoutes([...filterRoutes, { path: '*', redirect: '/404', hidden: true }])
        // 4.通过vuex获取到一个响应式的路由表数据
        // 5.点击导航进入页面显示正常 但是页面刷新或者输入url进入页面会白屏
        // 原因：router.addRoutes 这个方法是异步方法 进入到异步队列
        // 代码会先执行next跳转 当next跳转路由的时候路由表中还没有新加入的异步路由
        // 所以刷新页面 或者输入url会白屏
        store.commit('menu/setMenuList', filterRoutes)
        // 6.通过让路由守卫从新进入一次路由方式 进入到第二轮事件循环中
        // 第一轮中的异步队列中的方法就已经执行完成了
        next({
          ...to,
          replace: true// 进入页面不保留历史
        })
      }

      // console.log(store.state.user.userInfor)
      next()
    }
  } else {
    if (whileList.includes(to.path)) {
      next()
    } else {
      next('/login')
      NProgress.done()
    }
  }
})

// 路由后置守卫
// 当路由跳转结束后会触发
// 此时我们需要进度条
router.afterEach((to, from) => {
  nprogress.done()
})
